package codeflyer.server.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarException;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;

/**
 * @author CodeFlyer
 * @date May 4, 2020
 * @version 1.0
 */

public class JarUtils {
	
	//解压jar包
	/**
	 * 解压压缩包到指定目录
	 * 
	 * @param inputFile
	 * @param outputFile
	 */
	public static void unJar(File inputFile, File outputFile) {
		if (!outputFile.exists()) {
			outputFile.mkdirs();
		}
 
		JarFile jarFile = null;
		JarInputStream jarInput = null;
		JarEntry entry = null;
		OutputStream output = null;
		InputStream input = null;
		File file = null;
		try {
			jarFile = new JarFile(inputFile);
			jarInput = new JarInputStream(new FileInputStream(inputFile));
			String path = outputFile.getAbsolutePath().replaceAll("\\\\", "/") + "/";//File.separator;  //与系统相关的分隔符,就是斜杆,会根据系统来决定使用具体的分隔符
			while ((entry = jarInput.getNextJarEntry()) != null) {  //jar包条目的分隔符又是"/"
				// 从压缩文件里获取指定已压缩文件的输入流
				input = jarFile.getInputStream(entry);  //entry是jar包里所有文件的条目,包括文件夹
 
				// 拼装压缩后真实文件路径,jar包里的路径就是以“/”分割的
				String fileName = path + entry.getName(); //这里表示获取的entry只是jar包下的相对路径
				System.out.println(fileName);
 
				// 创建文件缺失的目录（不然会报异常：找不到指定文件）
				file = new File(fileName.substring(0, fileName.lastIndexOf("/")));//File.separator;  //这里表示jar包里的文件夹也要一起创建
				file.mkdirs();
 
				// 创建文件输出流
				output = new FileOutputStream(fileName);
 
				// 写出解压后文件数据
				write(input, output);
	
				output.close();
			}
		} catch (JarException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (output != null) {
					output.close();
				}
 
				if (jarInput != null) {
					jarInput.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 从输入流写入到输出流的方便方法 【注意】这个函数只会关闭输入流，且读写完成后会调用输出流的flush()函数，但不会关闭输出流！
	 * 
	 * @param input
	 * @param output
	 */
	private static void write(InputStream input, OutputStream output) {
		int len = -1;
		byte[] buff = new byte[1024];
		try {
			while ((len = input.read(buff)) != -1) {
				output.write(buff, 0, len);
			}
			output.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(input!=null) {
					input.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(output!=null) {
					output.close();
				}				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}


